{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线性回归实例\n",
    "- 手写一元线性回归\n",
    "- 手写梯度下降算法\n",
    "- 和Scikit-learn中的线性回归比较"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.linear_model import LinearRegression\n",
    "# 绘制三维图，此处用不上\n",
    "from mpl_toolkits.mplot3d import axes3d\n",
    "\n",
    "pd.set_option('display.notebook_repr_html', False)\n",
    "pd.set_option('display.max_columns', None)\n",
    "pd.set_option('display.max_rows', 150)\n",
    "pd.set_option('display.max_seq_items', None)\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "import seaborn as sns\n",
    "sns.set_context('notebook')\n",
    "sns.set_style('white')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.loadtxt('linear_regression_data1.txt', delimiter=',')\n",
    "#np.ones(data.shape[0])为截距项\n",
    "#np.r_是按行连接两个矩阵，就是把两矩阵上下相加，要求行数相等，类似于pandas中的concat()\n",
    "#np.c_是按列连接两个矩阵，就是把两矩阵左右相加，要求列数相等，类似于pandas中的merge()\n",
    "X = np.c_[np.ones(data.shape[0]), data[:,0]]\n",
    "Y = np.c_[data[:,1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Profit in $10,000s')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 散点图：s表示大小，c表示颜色，marker表示标记\n",
    "plt.scatter(X[:, 1], Y, s=30, c='b', marker='+', linewidths=1)\n",
    "# 横坐标的范围\n",
    "plt.xlim(4, 24)\n",
    "# 城市人口数量，单位：万\n",
    "plt.xlabel('Population of City in 10,000s')\n",
    "# 收入，单位：万美元\n",
    "plt.ylabel('Profit in $10,000s')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算损失函数，theta的初始值为大小为2的数组，对应自变量和截距项\n",
    "def computeCost(X, Y, theta=[[0], [0]]):\n",
    "    m = Y.size\n",
    "    J = 0\n",
    "    # h为线性拟合的函数，本质为一条连续直线\n",
    "    h = X.dot(theta)\n",
    "    # 最小二乘法，J即为损失函数\n",
    "    J = 1.0/(2*m)*(np.sum(np.square(h-Y)))\n",
    "    \n",
    "    return J"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32.072733877455676"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 初始损失函数值很大，后续使用梯度下降算法获取损失函数的最优解\n",
    "computeCost(X, Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 梯度下降算法，alpha为步长（超参数），num_iters为迭代轮次\n",
    "def gradientDescent(X, Y, theta=[[0], [0]], alpha=0.01, num_iters=1500):\n",
    "    m = Y.size\n",
    "    J_history = np.zeros(num_iters)\n",
    "    \n",
    "    for iter in np.arange(num_iters):\n",
    "        h = X.dot(theta)\n",
    "        #X.T表示x的转置矩阵，X.T.dot(h-Y)没有进行求和是因为它本身是线性代数运算，其值为所有乘积的和\n",
    "        theta = theta - alpha*(1.0/m)*(X.T.dot(h-Y))\n",
    "        J_history[iter] = computeCost(X, Y, theta)\n",
    "    return (theta, J_history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回归模型训练参数=> [-3.63029144  1.16636235]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'cost_J')"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 画出每一次迭代和损失函数变化\n",
    "theta, cost_J = gradientDescent(X, Y)\n",
    "# ravel指散开的意思，返回一个视图view。flatten也是打平的意思，但是其返回一份拷贝（降维）\n",
    "print('回归模型训练参数=>', theta.ravel())\n",
    "\n",
    "# 损失函数迭代曲线\n",
    "plt.plot(cost_J, c=\"r\")\n",
    "plt.xlabel('iterations')\n",
    "plt.ylabel('cost_J')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制数据分布散点图\n",
    "plt.scatter(X[:,1], Y, c='b', s=30)\n",
    "# 城市人口数量，单位：万\n",
    "plt.xlabel('Population of City in 10,000s')\n",
    "# 收入，单位：万美元\n",
    "plt.ylabel('Profit in $10,000s')\n",
    "\n",
    "# 自定义线性拟合的模型\n",
    "x = np.arange(5,23)\n",
    "y = theta[0] + theta[1]*x\n",
    "plt.plot(x, y, label='Linear regression (Gradient descent)')\n",
    "\n",
    "# 引入sklearn中的线性回归\n",
    "line_regr = LinearRegression()\n",
    "#ravel函数在降维时默认是行序优先，即将列向量转为行向量\n",
    "line_regr.fit(X[:, 1].reshape(-1, 1), Y.ravel())\n",
    "plt.plot(x, line_regr.intercept_ + line_regr.coef_ * x, label='Liner regression(Scikit_learn)')\n",
    "\n",
    "plt.xlim(4,24)\n",
    "plt.xlabel('Population of City in 10,000s')\n",
    "plt.ylabel('Profit in $10,000s')\n",
    "# 指定图例位置\n",
    "plt.legend(loc=4); "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.5万城市人口的收入== [4519.7678677]\n",
      "7万城市人口的收入== [45342.45012945]\n"
     ]
    }
   ],
   "source": [
    "#预测一下人口为35,000和70,000的城市的结果\n",
    "print(\"3.5万城市人口的收入==\", theta.T.dot([1,3.5])*10000)\n",
    "print(\"7万城市人口的收入==\", theta.T.dot([1,7])*10000)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
